package com.chezai.client.global.device;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
import android.text.TextUtils;
import android.widget.Toast;

import com.chezai.client.bean.CheckTime;
import com.chezai.client.bean.ReadIdCardBean;
import com.chezai.client.bean.Speech;
import com.chezai.client.global.TerminalApplication;
import com.chezai.client.utils.PackageUtils;
import com.chezai.client.utils.SpeechUtils;
import com.chezai.client.utils.ToastUtil;
import com.chezai.client.utils.Util;
import com.orhanobut.logger.Logger;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.security.InvalidParameterException;

import android_serialport_api.SerialPort;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * Describe 小鹿设备
 * Created by LZF on 2016/12/9.
 */
public class QHYC_C103Hardware extends DifferenceHardware {
    private static final String ACTION_SLIENT_INSTALL = "com.qhyc.install.action.SLIENT_INSTALL";
    private static final String KEY_SLIENT_INSTALL_PATH = "com.qhyc.install.key.PATH";
    private final String NO_CARD_STATUS = "0000000000000000";//没有放上身份证时返回的数据
    private final String CLOSE_ANTENNA_REQ = "AABB060000000C01000D";//关闭天线请求
    private final String CLOSE_ANTENNA_ACK = "AABB060011120C01000E";//关闭天线响应
    private final String SETTING_RF_READ_MODE_REQ = "AABB060000000801424B";//设置读卡模式请求
    private final String SETTING_RF_READ_MODE_ACK = "AABB060011120801000A";//设置读卡模式应答
    private final String OPEN_ANTENNA_REQ = "AABB060000000C01010C";//打开天线请求
    private final String OPEN_ANTENNA_ACK = "AABB060011120C01000E";//关闭天线请求
    private final String FINDING_RF_RED = "AABB0600000001030002";//寻卡请求
    private final String FINDING_RF_ACK = "AABB12001112010300";//寻卡应答
    private final String NO_CARD_OR_REREAD_ACK = "AABB0600111201031514";//无卡或第二次读卡
    private int noReadCardEvnt = 0;
    private OutputStream mOutputStream;
    private InputStream mInputStream;
    private ReadThread mReadThread;
    private SerialPort mSerialPort;
    private SendingThread mSendThread;

    @Override
    public String getSerialNumber(Context context) {
        String serialNum = "";
        try {
            String serialNumber = android.os.SystemProperties.get("gsm.serial");
            if (!TextUtils.isEmpty(serialNumber) && serialNumber.length() > 14) {
                serialNum = serialNumber.substring(0, 15);
            }
            if (!TextUtils.isEmpty(serialNum)) {
                if (serialNum.length() > 6) {
                    int n = 7;
                    serialNum = serialNum.substring(serialNum.length() - n, serialNum.length());
                }
            }
        } catch (Exception ignored) {

        }
        return serialNum;
    }


    @Override
    public void setCalibrateTime() {
        Observable.create(new ObservableOnSubscribe<Long>() {
            @Override
            public void subscribe(ObservableEmitter<Long> emitter) throws Exception {
                URL url = new URL("http://www.ggxueche.com/static/main/index.html");
                URLConnection uc = url.openConnection();
                uc.setConnectTimeout(3 * 1000);
                uc.connect();
                long time = uc.getDate();
                emitter.onNext(time);
            }
        }).subscribeOn(Schedulers.io())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long aLong) {
                        setSystemTime(aLong);
                        EventBus.getDefault().postSticky(new CheckTime(true));
                    }

                    @Override
                    public void onError(Throwable e) {
                        EventBus.getDefault().postSticky(new CheckTime(false));
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 设置时间
     *
     * @param time 服务器时间 时间戳
     */
    public void setSystemTime(long time) {
        Logger.t(TAG).e("setSystemTime: " + time);
        if (Build.VERSION.SDK_INT <= 26) {
            Intent settimeintent = new Intent("com.android.custom.timesetting");
            Long millis = time;
            settimeintent.putExtra("time", millis);
            TerminalApplication.getTerminalContext().sendBroadcast(settimeintent);
        } else {
            Intent intent = new Intent();
            intent.setAction("com.android.custom.timesetting");
            intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.AddApnReceiver"));
            intent.putExtra("time", time);
            TerminalApplication.getTerminalContext().sendBroadcast(intent);
        }

    }

    @Override
    public void openSettings(Context context) {
        Intent intent = new Intent("/");
        ComponentName cm = new ComponentName("com.android.settings", "com.android.settings.Settings");
        intent.setComponent(cm);
        intent.setAction("android.intent.action.VIEW");
        context.startActivity(intent);
    }

    @Override
    public long getPowerTime() {
        return 0;
    }

    @Override
    public boolean cameraIsCanUse() {
        return false;
    }

    @Override
    public boolean controlRelay(boolean open) {
        return false;
    }

    @Override
    public void installApk(Context context, String filePath) {
        //第一批设备没有AppInstaller.apk 只能手动点击安装
        boolean isInstalled = PackageUtils.isAvilible(new SoftReference<>(context), "com.qhyc.install");
        if (isInstalled) {
            String fileUrl = filePath;
            if (!TextUtils.isEmpty(filePath) && filePath.contains("file://")) {
                fileUrl = filePath.replace("file://", "");
            }
            Intent intent = new Intent();
            intent.setAction(ACTION_SLIENT_INSTALL);
            intent.putExtra(KEY_SLIENT_INSTALL_PATH, fileUrl);
            context.sendBroadcast(intent);
            Toast.makeText(context, "程序正在安装" + "--路径：" + fileUrl, Toast.LENGTH_LONG).show();
        } else {
            Intent intentPath = new Intent(Intent.ACTION_VIEW);
            intentPath.setDataAndType(Uri.parse(filePath), "application/vnd.android.package-archive");
            intentPath.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intentPath);
        }

    }

    @Override
    public void setAccPowerTime(Context context, long powerTime) {

    }

    @Override
    public void setScreenOrientation(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
    }

    @Override
    public boolean isNeedRotaingImage() {
        return true;
    }

    @Override
    public void disableNotificationBar(Context context) {

    }

    @Override
    public synchronized void rebootDevice(final Context context) {
        SpeechUtils.getInstance().playOrComposed(Speech.LOC_INVALID.getMsg(), Speech.LOC_INVALID.getFilePath());
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent();
                intent.setAction("com.android.custom.sys_reboot");
                context.sendBroadcast(intent);
            }
        }, 10 * 1000);
    }

    /**
     * QHYC设置APN
     *
     * @param ctx
     */
    private void setApn(Context ctx) {
        Intent intentAPN = new Intent();
        intentAPN.setAction("com.android.custom.write_APN");
        intentAPN.putExtra("name", "ggxueche");
        intentAPN.putExtra("type", "default");
        intentAPN.putExtra("apn", "gdgzltzw01.clfu.gzm2mapn");
        intentAPN.putExtra("mcc", "460");
        intentAPN.putExtra("mnc", "01");
        intentAPN.putExtra("protocol", "IPV4");
        intentAPN.putExtra("roaming_protocol", "IPV4");
        intentAPN.putExtra("flag", 0);
        ctx.sendBroadcast(intentAPN);
    }

    @Override
    public String readIcCard(Context context) {
        return "";
    }


    @Override
    public void readIDCard(Context context) {
        try {
            mSerialPort = TerminalApplication.getTerminalContext().getSerialPort();
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();
            Logger.t("readCard").d("mSerialPort= " + mSerialPort);
            /* Create a receiving thread */
            mReadThread = new ReadThread();
            mReadThread.start();
            mSendThread = new SendingThread();
            mSendThread.send(CLOSE_ANTENNA_REQ);
            mSendThread.start();
        } catch (SecurityException e) {
            ToastUtil.showToast(TerminalApplication.mContext, "You do not have read/write permission to the serial port.");
        } catch (IOException e) {
            ToastUtil.showToast(TerminalApplication.mContext, "The serial port can not be opened for an unknown reason.");
        } catch (InvalidParameterException e) {
            ToastUtil.showToast(TerminalApplication.mContext, "Please configure your serial port first.");
        }
    }

    //关闭串口
    public void closeSerialPort() {
        noReadCardEvnt = 0;
        if (mReadThread != null)
            mReadThread.interrupt();
        if (mSendThread != null)
            mSendThread.interrupt();
        TerminalApplication.getTerminalContext().closeSerialPort();
        mSerialPort = null;
    }

    private class ReadThread extends Thread {
        boolean closeAck = true;
        boolean settingAck = true;
        boolean openAck = true;

        @Override
        public void run() {
            super.run();
            while (!isInterrupted()) {
                int size;
                try {
                    byte[] buffer = new byte[64];
                    if (mInputStream == null) return;
                    if (mInputStream.available() > 0) {
                        size = mInputStream.read(buffer);
                        if (size > 0) {
                            BigInteger bigInteger = new BigInteger(1, buffer);
                            String ff = bigInteger.toString(16).toLowerCase();
                            if (TextUtils.isEmpty(ff) || TextUtils.equals(ff, "0")) {
                                closeSerialPort();
                                EventBus.getDefault().post(new ReadIdCardBean(ReadIdCardBean.STATUS_NO_CONNECT, ""));
                                return;
                            }
                            if (TextUtils.equals(ff.substring(0, CLOSE_ANTENNA_ACK.length()), CLOSE_ANTENNA_ACK.toLowerCase())) {
                                if (closeAck) {
                                    Logger.t("readCard").d("re 收到关闭天线响应");
                                    mSendThread.send(SETTING_RF_READ_MODE_REQ);
                                    closeAck = false;
                                    Logger.t("readCard").d("re 发送设置读卡模式指令");
                                } else if (openAck) {
                                    Logger.t("readCard").d("re 收到打开天线响应");
                                    mSendThread.send(FINDING_RF_RED);
                                    openAck = false;
                                    Logger.t("readCard").d("re 发送寻卡指令");
                                }
                            } else if (TextUtils.equals(ff.substring(0, SETTING_RF_READ_MODE_ACK.length()), SETTING_RF_READ_MODE_ACK.toLowerCase())) {
                                Logger.t("readCard").d("re 收到设置读卡模式响应");
                                if (settingAck) {
                                    mSendThread.send(OPEN_ANTENNA_REQ);
                                    settingAck = false;
                                    Logger.t("readCard").d("re 发送打开天线指令");
                                }
                            } else if (ff.startsWith(FINDING_RF_ACK.toLowerCase())) {
                                String realId = ff.replace(FINDING_RF_ACK.toLowerCase(), "");
                                if (realId.contains("aa00")) {
                                    realId = realId.replace("aa00", "aa");
                                }
                                String idCard = realId.substring(0, 16);
                                Logger.t("readCard").d("读卡成功 卡号为 " + idCard);
                                closeSerialPort();
                                EventBus.getDefault().post(new ReadIdCardBean(ReadIdCardBean.STATUS_SUCESS, idCard));
                            } else if (TextUtils.equals(ff.substring(0, NO_CARD_OR_REREAD_ACK.length()), NO_CARD_OR_REREAD_ACK.toLowerCase())) {
                                String idCard = ff.replace(NO_CARD_OR_REREAD_ACK.toLowerCase(), "").substring(0, 16);
                                if (TextUtils.equals(idCard, NO_CARD_STATUS)) {
                                    Logger.t("readCard").d("没有放卡");
                                    if (noReadCardEvnt % 100 == 0) {
                                        EventBus.getDefault().post(new ReadIdCardBean(ReadIdCardBean.STATUS_ERROR, ""));
                                    }
                                    noReadCardEvnt++;
                                } else {
                                    Logger.t("readCard").d("读卡成功 卡号为 " + idCard);
                                }
                            }
                        }
                    }
                    SystemClock.sleep(100);
                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }

    private class SendingThread extends Thread {
        String msg = "";

        @Override
        public void run() {
            while (!isInterrupted()) {
                try {
                    if (mOutputStream != null) {
                        mOutputStream.write(Util.hexStringToBytes(msg));
                    } else {
                        return;
                    }
                    SystemClock.sleep(100);
                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }

        public void send(String msg) {
            this.msg = msg;
        }
    }

}
